下面这段代码是Flask的主页上给出的,这是一段Hello World级别的代码段,但是里面包含的概念可一点都不简单。
1 | from flask import Flask |
这里面的 `@app.route(‘/‘)` 到底是什么意思呢,具体又是如何实现的呢?很多初学者都是很迷茫。我在集中精力理解了装饰器之后,慢慢的就对app.route 这个装饰器的原理以及目的有了了解了。
以前写过一篇文章,详细说明了装饰器的概念:搞懂Python装饰器 要是忘了可以随时复习一下。
给装饰器传参数
需要外嵌一个工厂函数,调用这个函数,然后返回函数的装饰器
1 | def decorator_factory(enter_message, exit_message): |
注意,这里使用 @decorator_factory("Start", "End")
的时候,实际调用的是 decorator_factory
函数。相当于如下调用:
1 | decorator_factory("Start", "End")(hello) |
输出结果为:
创建自己的Flask类
现在我们已经有了足够的装饰器的背景知识,可以模拟一下Flask对象里面的内容。
创建route装饰器
我们知道,Flask是一个类,而类方法也可以被用作装饰器。
1 | class MyFlask(): |
这里不想修改被装饰函数的行为,只是想获取被装饰函数的引用,以便后面注册这个函数用。
添加一个存储路由的字典
现在,需要一个变量去存储路由和其关联的函数
1 | class MyFlask(): |
当给定的路径被注册过则返回函数运行结果,当路径尚未注册时则抛出一个异常。
解释动态URL
形如 `@app.route(“/hello/
使用正则表达式
1 | import re |
输出结果为:{'username': 'ains'}
现在需要使用 (pattern, view_function)
这个元组来保存路径编译变成一个正则表达式和注册函数的关系。然后在装饰器中,把编译好的正则表达式和注册函数的元组保存在列表中。
1 | routes = [] |
接下来,再创建一个访问routes变量的函数,如果匹配上,则返回正则表达式匹配组和注册函数组成的元组。
1 | def get_route_match(path): |
再接下来要找出调用view_function的方法,使用来自正则表达式匹配组字典的正确参数
1 | def serve(path): |
改好的MyFlask类如下:
1 | class MyFlask(): |
运行一段带参数的试试
1 | app = MyFlask() |
下面是程序运行的引用关系图